#include <stdio.h>
#include <stdlib.h>

/*
* Definition des Listenknotentyps
*/
struct DListNode {
double m_data;
struct DListNode* m_next;
struct DListNode* m_prev;
};

int main ()
{
/*Temporaere Variable zur Aufnahme der Eingabedaten */
   double tem_data;

/*Zeiger auf Anfang und Ende der Liste */
   struct DListNode* list_begin = NULL;
   struct DListNode* list_end = NULL;

/* Temporaerer Zeiger auf Listenknoten */
   struct DListNode* tem_node;

/* Solange Eingaben kommen ... */
   while (scanf ("%lf", &tem_data) == 1) {

     /* Speicher fuer neuen Listenknoten anfordern */
     tem_node = malloc (sizeof (struct DListNode));

/* Auf Speicherfehler testen ... */
     if (tem_node == NULL) {
       fprintf (stderr, "\aSpeicherfehler!\n");
       exit (1);
     }

/* Anwendungsinformation eintragen */
     tem_node -> m_data = tem_data;

/* Der Vorgaenger des neuen Knotens
   ist der bislang letzte Knoten */
     tem_node -> m_prev = list_end;

/* Der Nachfolger des letzten Knotens
        ist nicht definiert, also NULL */
     tem_node -> m_next = NULL;

     if (list_begin == NULL) {
       /* Falls noch kein Listenanfang definiert ist,
            dann ist der gerade angelegte Knoten der
            Anfang der Liste */
       list_begin = tem_node;
     } else {
       /* Der Nachfolger des bislang letzten Knotens
          ist der gerade neu angelegte Knoten */
       list_end -> m_next = tem_node;
     }

     /* Der gerade neu angelegte Knoten
        ist nun der letzte Knoten */
     list_end = tem_node;

   }

   /* Ausgabe vorwaerts ... */
   tem_node = list_begin;

   while (tem_node != NULL) {

     printf ("%f\n", tem_node -> m_data);

     /* Zum nachsten Knoten weitergehen ... */
     tem_node = tem_node -> m_next;

   }

   /* Ausgabe rueckwaerts ... */
   tem_node = list_end;

   while (tem_node != NULL) {
   printf ("%f\n", tem_node -> m_data);
  
      /* Zum nachsten Knoten weitergehen ... */
      tem_node = tem_node -> m_prev;

     }

}
